# =============================================================================
# April 24 2025
# R code used to produce all results, tables, and figures in the SI Online Appendix L
# Rebecca Cordell
# Unpacking the Role of In-Group Bias in US Public Opinion on Human Rights Violations
# American Journal of Political Science
# https://doi.org/10.7910/DVN/TGAL7M
# =============================================================================

# Clear work environment
rm(list=ls())

# Install Packages
#install.packages("dplyr")
#install.packages("ggplot2")
#install.packages("forcats")
#install.packages("ggpubr")
#install.packages("ggeasy")
#install.packages("lemon")
#install.packages("sandwich")
#install.packages("survey")
#install.packages("lmtest")
#install.packages("remotes")
#remotes::install_version("cregg", version = "0.4.0")

# Required Packages
library("dplyr")
library("ggplot2")
library("forcats")
library("ggpubr")
library("sandwich")
library("survey")
library("lmtest")
library("cregg")
library("ggeasy")
library("lemon")

options(scipen = 999)
options(warn=-1)

# -----------------------------------------------------------------------------
# Read in data
# -----------------------------------------------------------------------------

hr_survey<-read.csv("cordell_ingroupbiashumanrights_data.csv", header=TRUE, stringsAsFactors = FALSE)

# =============================================================================
# Figure L.1: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Education
# =============================================================================

# Create dummy variable
hr_survey$resp_educ_highlow <- ifelse(hr_survey$resp_educ %in% c("College", "Post-grad"), "Degree", "No Degree")

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_educ_highlow")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l1_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_educ_highlow)

# Model 2
fig_l1_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_educ_highlow)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l1_m1 <- fig_l1_m1[fig_l1_m1$feature %in% group_vars,]
fig_l1_m2 <- fig_l1_m2[fig_l1_m2$feature %in% group_vars,]

# Exclude NA values
fig_l1_m1 <- fig_l1_m1[!is.na(fig_l1_m1$estimate),]
fig_l1_m2 <- fig_l1_m2[!is.na(fig_l1_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l1_all <- rbind(fig_l1_m1, fig_l1_m2) 

# Subset by resp_educ_highlow
fig_l1_all_highered <- filter(fig_l1_all, resp_educ_highlow == "Degree")
fig_l1_all_lowered <- filter(fig_l1_all, resp_educ_highlow == "No Degree")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l1_all_highered <- dplyr::bind_rows(
  fig_l1_all_highered,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l1_all_lowered <- dplyr::bind_rows(
  fig_l1_all_lowered,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l1_all_highered <- fig_l1_all_highered %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l1_all_lowered <- fig_l1_all_lowered %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l1_all_highered <- fig_l1_all_highered %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l1_all_lowered <- fig_l1_all_lowered %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l1_m1_highered <- filter(fig_l1_all_highered, outcome == "outcome1")
fig_l1_m2_highered <- filter(fig_l1_all_highered, outcome == "outcome2")
fig_l1_m1_lowered <- filter(fig_l1_all_lowered, outcome == "outcome1")
fig_l1_m2_lowered <- filter(fig_l1_all_lowered, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Higher education - disapproval forced-choice 
fig_l1_m1_highered_plot <- ggplot(fig_l1_m1_highered, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Higher education - disapproval ratings-based
fig_l1_m2_highered_plot <- ggplot(fig_l1_m2_highered, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.60, 0.77)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Lower education - disapproval forced choice
fig_l1_m1_lowered_plot <- ggplot(fig_l1_m1_lowered, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Lower education - disapproval ratings-based
fig_l1_m2_lowered_plot <- ggplot(fig_l1_m2_lowered, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.60, 0.77)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.1
fig_l1_highered_plot<-ggarrange(fig_l1_m1_highered_plot, NULL, fig_l1_m2_highered_plot,
                                nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l1_highered_plot<-annotate_figure(fig_l1_highered_plot, top = text_grob("Higher education respondents", size = 14))
fig_l1_lowered_plot<-ggarrange(fig_l1_m1_lowered_plot, NULL, fig_l1_m2_lowered_plot,
                               nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l1_lowered_plot<-annotate_figure(fig_l1_lowered_plot, top = text_grob("Lower education respondents", size = 14))
pdf('figure_l1.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l1_highered_plot, fig_l1_lowered_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()

# =============================================================================
# Figure L.2: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Gender
# =============================================================================

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_gender")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l2_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_gender)

# Model 2
fig_l2_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_gender)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l2_m1 <- fig_l2_m1[fig_l2_m1$feature %in% group_vars,]
fig_l2_m2 <- fig_l2_m2[fig_l2_m2$feature %in% group_vars,]

# Exclude NA values
fig_l2_m1 <- fig_l2_m1[!is.na(fig_l2_m1$estimate),]
fig_l2_m2 <- fig_l2_m2[!is.na(fig_l2_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l2_all <- rbind(fig_l2_m1, fig_l2_m2) 

# Subset by resp_gender
fig_l2_all_female <- filter(fig_l2_all, resp_gender == "Female")
fig_l2_all_male <- filter(fig_l2_all, resp_gender == "Male")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l2_all_female <- dplyr::bind_rows(
  fig_l2_all_female,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l2_all_male <- dplyr::bind_rows(
  fig_l2_all_male,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l2_all_female <- fig_l2_all_female %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l2_all_male <- fig_l2_all_male %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l2_all_female <- fig_l2_all_female %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l2_all_male <- fig_l2_all_male %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l2_m1_female <- filter(fig_l2_all_female, outcome == "outcome1")
fig_l2_m2_female <- filter(fig_l2_all_female, outcome == "outcome2")
fig_l2_m1_male <- filter(fig_l2_all_male, outcome == "outcome1")
fig_l2_m2_male <- filter(fig_l2_all_male, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Female - disapproval forced-choice
fig_l2_m1_female_plot <- ggplot(fig_l2_m1_female, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Female - disapproval ratings-based
fig_l2_m2_female_plot <- ggplot(fig_l2_m2_female, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.64, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Male - disapproval forced choice
fig_l2_m1_male_plot <- ggplot(fig_l2_m1_male, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Male - disapproval ratings-based
fig_l2_m2_male_plot <- ggplot(fig_l2_m2_male, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.64, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.2
fig_l2_female_plot<-ggarrange(fig_l2_m1_female_plot, NULL, fig_l2_m2_female_plot,
                              nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l2_female_plot<-annotate_figure(fig_l2_female_plot, top = text_grob("Female respondents", size = 14))
fig_l2_male_plot<-ggarrange(fig_l2_m1_male_plot, NULL, fig_l2_m2_male_plot,
                            nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l2_male_plot<-annotate_figure(fig_l2_male_plot, top = text_grob("Male respondents", size = 14))
pdf('figure_l2.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l2_female_plot, fig_l2_male_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()

# =============================================================================
# Figure L.3: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Age
# =============================================================================

# Create dummy variable
hr_survey$resp_age_oldyoung <- ifelse(hr_survey$resp_age >= 49, "Older", "Younger")

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_age_oldyoung")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l3_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_age_oldyoung)

# Model 2
fig_l3_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_age_oldyoung)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l3_m1 <- fig_l3_m1[fig_l3_m1$feature %in% group_vars,]
fig_l3_m2 <- fig_l3_m2[fig_l3_m2$feature %in% group_vars,]

# Exclude NA values
fig_l3_m1 <- fig_l3_m1[!is.na(fig_l3_m1$estimate),]
fig_l3_m2 <- fig_l3_m2[!is.na(fig_l3_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l3_all <- rbind(fig_l3_m1, fig_l3_m2) 

# Subset by resp_age_oldyoung
fig_l3_all_older <- filter(fig_l3_all, resp_age_oldyoung == "Older")
fig_l3_all_younger <- filter(fig_l3_all, resp_age_oldyoung == "Younger")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l3_all_older <- dplyr::bind_rows(
  fig_l3_all_older,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l3_all_younger <- dplyr::bind_rows(
  fig_l3_all_younger,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l3_all_older <- fig_l3_all_older %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l3_all_younger <- fig_l3_all_younger %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l3_all_older <- fig_l3_all_older %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l3_all_younger <- fig_l3_all_younger %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l3_m1_older <- filter(fig_l3_all_older, outcome == "outcome1")
fig_l3_m2_older <- filter(fig_l3_all_older, outcome == "outcome2")
fig_l3_m1_younger <- filter(fig_l3_all_younger, outcome == "outcome1")
fig_l3_m2_younger <- filter(fig_l3_all_younger, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Older - disapproval forced-choice 
fig_l3_m1_older_plot <- ggplot(fig_l3_m1_older, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Older - disapproval ratings-based
fig_l3_m2_older_plot <- ggplot(fig_l3_m2_older, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.64, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Younger - disapproval forced choice
fig_l3_m1_younger_plot <- ggplot(fig_l3_m1_younger, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Younger - disapproval ratings-based
fig_l3_m2_younger_plot <- ggplot(fig_l3_m2_younger, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.64, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.3
fig_l3_older_plot<-ggarrange(fig_l3_m1_older_plot, NULL, fig_l3_m2_older_plot,
                             nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l3_older_plot<-annotate_figure(fig_l3_older_plot, top = text_grob("Older respondents", size = 14))
fig_l3_younger_plot<-ggarrange(fig_l3_m1_younger_plot, NULL, fig_l3_m2_younger_plot,
                               nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l3_younger_plot<-annotate_figure(fig_l3_younger_plot, top = text_grob("Younger respondents", size = 14))
pdf('figure_l3.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l3_older_plot, fig_l3_younger_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()

# =============================================================================
# Figure L.4: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Political Ideology
# =============================================================================

# Create dummy variable
hr_survey$resp_libcon <- ifelse(
  hr_survey$resp_ideo %in% c("Very liberal", "Liberal"), "Liberal",
  ifelse(hr_survey$resp_ideo %in% c("Very conservative", "Conservative"), "Conservative", NA))

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_libcon")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l4_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_libcon)

# Model 2
fig_l4_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_libcon)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l4_m1 <- fig_l4_m1[fig_l4_m1$feature %in% group_vars,]
fig_l4_m2 <- fig_l4_m2[fig_l4_m2$feature %in% group_vars,]

# Exclude NA values
fig_l4_m1 <- fig_l4_m1[!is.na(fig_l4_m1$estimate),]
fig_l4_m2 <- fig_l4_m2[!is.na(fig_l4_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l4_all <- rbind(fig_l4_m1, fig_l4_m2) 

# Subset by resp_libcon
fig_l4_all_lib <- filter(fig_l4_all, resp_libcon == "Liberal")
fig_l4_all_con <- filter(fig_l4_all, resp_libcon == "Conservative")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l4_all_lib <- dplyr::bind_rows(
  fig_l4_all_lib,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l4_all_con <- dplyr::bind_rows(
  fig_l4_all_con,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l4_all_lib <- fig_l4_all_lib %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l4_all_con <- fig_l4_all_con %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l4_all_lib <- fig_l4_all_lib %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l4_all_con <- fig_l4_all_con %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l4_m1_lib <- filter(fig_l4_all_lib, outcome == "outcome1")
fig_l4_m2_lib <- filter(fig_l4_all_lib, outcome == "outcome2")
fig_l4_m1_con <- filter(fig_l4_all_con, outcome == "outcome1")
fig_l4_m2_con <- filter(fig_l4_all_con, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Liberal - disapproval forced-choice 
fig_l4_m1_lib_plot <- ggplot(fig_l4_m1_lib, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Liberal - disapproval ratings-based
fig_l4_m2_lib_plot <- ggplot(fig_l4_m2_lib, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.6, 0.83)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Conservative - disapproval forced choice
fig_l4_m1_con_plot <- ggplot(fig_l4_m1_con, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Conservative - disapproval ratings-based
fig_l4_m2_con_plot <- ggplot(fig_l4_m2_con, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.6, 0.83)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.4
fig_l4_lib_plot<-ggarrange(fig_l4_m1_lib_plot, NULL, fig_l4_m2_lib_plot,
                               nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l4_lib_plot<-annotate_figure(fig_l4_lib_plot, top = text_grob("Liberal respondents", size = 14))
fig_l4_con_plot<-ggarrange(fig_l4_m1_con_plot, NULL, fig_l4_m2_con_plot,
                                    nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l4_con_plot<-annotate_figure(fig_l4_con_plot, top = text_grob("Conservative respondents", size = 14))
pdf('figure_l4.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l4_lib_plot, fig_l4_con_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()

# =============================================================================
# Figure L.5: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Interest in Human Rights
# =============================================================================

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_hrinterest")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l5_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_hrinterest)

# Model 2
fig_l5_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_hrinterest)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l5_m1 <- fig_l5_m1[fig_l5_m1$feature %in% group_vars,]
fig_l5_m2 <- fig_l5_m2[fig_l5_m2$feature %in% group_vars,]

# Exclude NA values
fig_l5_m1 <- fig_l5_m1[!is.na(fig_l5_m1$estimate),]
fig_l5_m2 <- fig_l5_m2[!is.na(fig_l5_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l5_all <- rbind(fig_l5_m1, fig_l5_m2) 

# Subset by resp_hrinterest
fig_l5_all_hrinterest <- filter(fig_l5_all, resp_hrinterest == "Interested")
fig_l5_all_hrdisinterest <- filter(fig_l5_all, resp_hrinterest == "Disinterested")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l5_all_hrinterest <- dplyr::bind_rows(
  fig_l5_all_hrinterest,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l5_all_hrdisinterest <- dplyr::bind_rows(
  fig_l5_all_hrdisinterest,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l5_all_hrinterest <- fig_l5_all_hrinterest %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l5_all_hrdisinterest <- fig_l5_all_hrdisinterest %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l5_all_hrinterest <- fig_l5_all_hrinterest %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l5_all_hrdisinterest <- fig_l5_all_hrdisinterest %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l5_m1_hrinterest <- filter(fig_l5_all_hrinterest, outcome == "outcome1")
fig_l5_m2_hrinterest <- filter(fig_l5_all_hrinterest, outcome == "outcome2")
fig_l5_m1_hrdisinterest <- filter(fig_l5_all_hrdisinterest, outcome == "outcome1")
fig_l5_m2_hrdisinterest <- filter(fig_l5_all_hrdisinterest, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Interested - disapproval forced-choice
fig_l5_m1_hrinterest_plot <- ggplot(fig_l5_m1_hrinterest, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Interested - disapproval ratings-based
fig_l5_m2_hrinterest_plot <- ggplot(fig_l5_m2_hrinterest, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.55, 0.76)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Disinterested - disapproval forced choice
fig_l5_m1_hrdisinterest_plot <- ggplot(fig_l5_m1_hrdisinterest, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Disinterested - disapproval ratings-based
fig_l5_m2_hrdisinterest_plot <- ggplot(fig_l5_m2_hrdisinterest, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.55, 0.76)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.5
fig_l5_hrinterest_plot<-ggarrange(fig_l5_m1_hrinterest_plot, NULL, fig_l5_m2_hrinterest_plot,
                                  nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l5_hrinterest_plot<-annotate_figure(fig_l5_hrinterest_plot, top = text_grob("Interested in human rights respondents", size = 14))
fig_l5_hrdisinterest_plot<-ggarrange(fig_l5_m1_hrdisinterest_plot, NULL, fig_l5_m2_hrdisinterest_plot,
                                     nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l5_hrdisinterest_plot<-annotate_figure(fig_l5_hrdisinterest_plot, top = text_grob("Disinterested in human rights respondents", size = 14))
pdf('figure_l5.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l5_hrinterest_plot, fig_l5_hrdisinterest_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()

# =============================================================================
# Figure L.6: Effect of Group Identity Attributes, Heterogeneous Treatment Effects Test for Partisan Strength
# =============================================================================

# Create dummy variable
hr_survey$resp_strongweak <- ifelse(
  hr_survey$resp_party7 %in% c("Strong Democrat", "Strong Republican"), "Strong",
  ifelse(hr_survey$resp_party7 %in% c("Not very strong Democrat", "Not very strong Republican"), "Weak", NA))

# Convert regression variables into factors
factor_vars <- c("perp_match", "agent", "type", "scope", "targ_nonstate",
                 "targ_race_match", "targ_relig_match", "targ_citiz_match",
                 "frame", "elite_match", "resp_strongweak")
hr_survey[factor_vars] <- lapply(hr_survey[factor_vars], as.factor)

# -----------------------------------------------------------------------------
# Calculate subgroup marginal means
# -----------------------------------------------------------------------------

# Model 1
fig_l6_m1 <- cregg::cj(hr_survey, outcome1 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_strongweak)

# Model 2
fig_l6_m2 <- cregg::cj(hr_survey, outcome2 ~ perp_match + agent + type + scope + targ_nonstate + targ_race_match + targ_relig_match + targ_citiz_match + frame + elite_match, id = ~id, estimate = "mm", by = ~resp_strongweak)

# Subset group identity dummy variables
group_vars <- c("perp_match", "targ_race_match", 
                "targ_relig_match", "targ_citiz_match", 
                "elite_match")
fig_l6_m1 <- fig_l6_m1[fig_l6_m1$feature %in% group_vars,]
fig_l6_m2 <- fig_l6_m2[fig_l6_m2$feature %in% group_vars,]

# Exclude NA values
fig_l6_m1 <- fig_l6_m1[!is.na(fig_l6_m1$estimate),]
fig_l6_m2 <- fig_l6_m2[!is.na(fig_l6_m2$estimate),]

# -----------------------------------------------------------------------------
# Prepare Figures
# -----------------------------------------------------------------------------

# Combine models
fig_l6_all <- rbind(fig_l6_m1, fig_l6_m2) 

# Subset by resp_strongweak
fig_l6_all_strong <- filter(fig_l6_all, resp_strongweak == "Strong")
fig_l6_all_weak <- filter(fig_l6_all, resp_strongweak == "Weak")

# Create group identity variable labels
variable_labels <- c(
  "perp_match" = "Perpetrator (partisanship)",
  "targ_race_match" = "Target (race)",
  "targ_relig_match" = "Target (religion)",
  "targ_citiz_match" = "Target (citizenship)",
  "elite_match" = "Elite cue (partisanship)"
)
fig_l6_all_strong <- dplyr::bind_rows(
  fig_l6_all_strong,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)
fig_l6_all_weak <- dplyr::bind_rows(
  fig_l6_all_weak,
  do.call(rbind, lapply(names(variable_labels), function(variable) {
    data.frame(
      outcome = c("outcome1", "outcome2"),
      variable = variable_labels[variable],
      level = variable_labels[variable],
      estimate = NA, lower = NA, upper = NA
    )
  }))
)

# Set factor order
fig_l6_all_strong <- fig_l6_all_strong %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())
fig_l6_all_weak <- fig_l6_all_weak %>%
  mutate(level = factor(level, levels = c("Perpetrator (partisanship)", "perp_in", "perp_out",
                                          "Target (race)", "race_in", "race_out",
                                          "Target (religion)", "relig_in", "relig_out",
                                          "Target (citizenship)", "citiz_in", "citiz_out",
                                          "Elite cue (partisanship)", "elite_in", "elite_out")) %>% fct_rev())

# Create respondents variable (in-groups vs. out-groups)
fig_l6_all_strong <- fig_l6_all_strong %>%
  mutate(Respondents = case_when(
    grepl("_in$", level) ~ "In-group",   
    grepl("_out$", level) ~ "Out-group", 
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))
fig_l6_all_weak <- fig_l6_all_weak %>%
  mutate(Respondents = case_when(
    grepl("_out$", level) ~ "Out-group",  
    grepl("_in$", level) ~ "In-group",  
    level %in% c("Perpetrator (partisanship)", "Target (race)", 
                 "Target (religion)", "Target (citizenship)", "Elite cue (partisanship)") ~ "In-group", 
    TRUE ~ level
  )) %>%
  mutate(Respondents = factor(Respondents, levels = c("In-group", "Out-group")))

# Separate models
fig_l6_m1_strong <- filter(fig_l6_all_strong, outcome == "outcome1")
fig_l6_m2_strong <- filter(fig_l6_all_strong, outcome == "outcome2")
fig_l6_m1_weak <- filter(fig_l6_all_weak, outcome == "outcome1")
fig_l6_m2_weak <- filter(fig_l6_all_weak, outcome == "outcome2")

# -----------------------------------------------------------------------------
# Create Figures
# -----------------------------------------------------------------------------

# Create panel (a) Strong partisans - disapproval forced-choice
fig_l6_m1_strong_plot <- ggplot(fig_l6_m1_strong, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(a) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (b) Strong partisans - disapproval ratings-based
fig_l6_m2_strong_plot <- ggplot(fig_l6_m2_strong, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.63, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(b) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank(),
    legend.position = "none"
  ) +
  labs(color = NULL)

# Create panel (c) Weak partisans - disapproval forced choice
fig_l6_m1_weak_plot <- ggplot(fig_l6_m1_weak, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip() +
  geom_hline(yintercept = 0.5, size = 0.2, color = "black") +
  scale_y_symmetric(mid = 0.5) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(c) Disapproval forced-choice") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Create panel (d) Weak partisans - disapproval ratings-based
fig_l6_m2_weak_plot <- ggplot(fig_l6_m2_weak, aes(x = level, y = estimate, colour = Respondents)) +
  geom_point() +
  geom_errorbar(aes(ymin = lower, ymax = upper), size = 0.3, width = 0.2) +
  scale_x_discrete(labels = c(
    "", "Elite cue (partisanship)", "", 
    "", "Target (citizenship)", "", 
    "", "Target (religion)", "", 
    "", "Target (race)", "", 
    "","Perpetrator (partisanship)",""
  )) +
  xlab('') + ylab('Marginal mean') +
  coord_flip(ylim = c(0.63, 0.75)) +
  theme_classic(base_size = 10) +
  scale_colour_grey() +
  easy_center_title() +
  ggtitle("(d) Disapproval ratings-based") +
  theme(
    axis.text.x = element_text(colour = "black"),
    axis.text.y = element_text(colour = "black"),
    axis.title.x = element_text(margin = margin(t = 10)),
    axis.ticks.y = element_blank()
  ) +
  labs(color = NULL)

# Print Figure L.6
fig_l6_strong_plot<-ggarrange(fig_l6_m1_strong_plot, NULL, fig_l6_m2_strong_plot,
                                    nrow = 1, common.legend = F, legend = NULL, ncol = 3, widths = c(1, 0.09, 1))
fig_l6_strong_plot<-annotate_figure(fig_l6_strong_plot, top = text_grob("Strong partisan respondents", size = 14))
fig_l6_weak_plot<-ggarrange(fig_l6_m1_weak_plot, NULL, fig_l6_m2_weak_plot,
                                  nrow = 1, common.legend = T, legend = "bottom", ncol = 3, widths = c(1, 0.09, 1))
fig_l6_weak_plot<-annotate_figure(fig_l6_weak_plot, top = text_grob("Weak partisan respondents", size = 14))
pdf('figure_l6.pdf', width = 8.26, height = 5.82)
ggarrange(fig_l6_strong_plot, fig_l6_weak_plot,
          nrow = 2, common.legend = T, legend = "bottom", ncol=1, heights = c(1, 1.1))
dev.off()